package com.mg.utils;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;


public class JsonUtils {

    private static ObjectMapper objectMapper = new ObjectMapper();
    private static ObjectMapper agentObjectMapper = new ObjectMapper();

    // 指定日期类型的格式化
    static {
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * 字符串转为bean
     *
     * @param content
     * @param valueType
     * @return
     */
    public static <T> T toAgentBean(String content, Class<T> valueType) {
        try {
            return agentObjectMapper.readValue(content, valueType);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 字符串转为bean
     *
     * @param content
     * @param valueType
     * @return
     */
    public static <T> T toBean(String content, Class<T> valueType) throws IOException {
        return objectMapper.readValue(content, valueType);
    }

    /**
     * 字符串转为List
     *
     * @param content
     * @param T
     * @return
     */
    public static <T> List<T> toList(String content, Class<T> T) {
        try {
            JavaType javaType = objectMapper.getTypeFactory()
                    .constructParametricType(List.class, T);
            return objectMapper.readValue(content, javaType);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 字符串转为Array
     *
     * @param content
     * @param T
     * @return
     */
    public static <T> T[] toArray(String content, Class<T> T) {
        try {
            List<T> list = JsonUtils.toList(content, T);
            @SuppressWarnings("unchecked")
            T[] a = (T[]) java.lang.reflect.Array.newInstance(T, list.size());
            return list.toArray(a);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * List串转为Array
     *
     * @param list
     * @param T
     * @return
     */
    public static <T> T[] toArray(List<T> list, Class<T> T) {
        try {
            @SuppressWarnings("unchecked")
            T[] a = (T[]) java.lang.reflect.Array.newInstance(T, list.size());
            return list.toArray(a);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 字符串转为Map<String, Object>
     *
     * @param content
     * @return
     */
    public static Map<String, Object> toMap(String content) {
        try {
            return objectMapper.readValue(content,
                    new TypeReference<Map<String, Object>>() {
                    });
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 对象转为Map<String, Object>
     *
     * @param object
     * @return
     */
    public static Map<String, Object> toMap(Object object) {
        try {
            return objectMapper.convertValue(object,
                    new TypeReference<Map<String, Object>>() {
                    });
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static <T, V> Map<T, V> toJavaMap(String jsonString,
                                             Class<T> keyClass, Class<V> valueClass) throws Exception {
        return objectMapper.readValue(jsonString, objectMapper.getTypeFactory()
                .constructMapLikeType(Map.class, keyClass, valueClass));
    }

    /**
     * 把JavaBean转换为json字符串 普通对象转换：toJson(Student) List转换：toJson(List)
     * Map转换:toJson(Map) 我们发现不管什么类型，都可以直接传入这个方法
     *
     * @param object JavaBean对象
     * @return json字符串
     */
    public static String toJson(Object object) throws JsonProcessingException {
        return objectMapper.writeValueAsString(object);

    }

    public static String toAgentJson(Object object) {
        try {
            return agentObjectMapper.writeValueAsString(object);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


    /**
     * 输出
     *
     * @param response
     * @param object
     */
    public static void writeJson(HttpServletResponse response, Object object) throws JsonProcessingException {
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        PrintWriter print = null;
        try {
            print = response.getWriter();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if (object != null) {
            print.write(toJson(object).toString());
        }
    }


}